package com.itlong.cloud.controller.welink;

import com.itlong.cloud.POJO.PO.WelinkBindRelationPO;
import com.itlong.cloud.POJO.VO.MessageVO;
import com.itlong.cloud.POJO.VO.miniprogram.WelinkUserVO;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.constants.RedisConstant;
import com.itlong.cloud.enumerate.ecode.BaseErrorCodeEnum;
import com.itlong.cloud.enumerate.ecode.MiniProgramErrorCodeEnum;
import com.itlong.cloud.enumerate.ecode.PropertyErrorCodeEnum;
import com.itlong.cloud.iottp.IIotTpSmsServiceClient;
import com.itlong.cloud.service.RedisService;
import com.itlong.cloud.thrown.DataAccessException;
import com.itlong.cloud.user.miniprogram.IWelinkServiceClient;
import com.itlong.cloud.utils.encrypt.Md5EncryptUtil;
import com.itlong.cloud.utils.words.NumberHandlerUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

/**
 * <desc>
 *      welink登录业务控制器
 * </desc>
 *
 * @createDate 2020/03/19
 */
@RestController
@RequestMapping("welink")
@RefreshScope
public class WelinkLoginController {
    private static final Logger LOG = LoggerFactory.getLogger(WelinkLoginController.class);

    @Value("${" + PlatformConstants.MINI_PROGRAM_REQUEST_PARAMS_ENCRYPT_KEY + "}")
    public String MINI_PROGRAM_REQUEST_PARAMS_ENCRYPT_KEY;

    @Autowired
    IWelinkServiceClient iWelinkServiceClient;

    @Autowired
    RedisService redisService;

    @Autowired
    IIotTpSmsServiceClient iIotTpSmsServiceClient;
    /**
     * <desc>
     *      welink登录
     * </desc>
     *
     * @param sign
     * @param createTime
     * @param code
     * @return
     * @author Jiaqi.X
     * @createDate 2020/03/19
     */
    @PostMapping(path = "/user/login")
    @ResponseBody
    public Object login(String sign,String code,String createTime,HttpServletRequest request){
        try {
            code = request.getAttribute("code") == null ? null : request.getAttribute("code").toString();
            createTime = request.getAttribute("createTime") == null ? null : request.getAttribute("createTime").toString();
            sign = request.getAttribute("sign") == null ? null : request.getAttribute("sign").toString();
            if (StringUtils.isEmpty(code) || StringUtils.isEmpty(createTime)) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            //验签
            Map<String, String> params = new HashMap<>();
            params.put("createTime", createTime);
            params.put("code", code);
            //验证签名
            if (!Md5EncryptUtil.checkAppSignValue(params, sign, MINI_PROGRAM_REQUEST_PARAMS_ENCRYPT_KEY)) {
                return new MessageVO(MiniProgramErrorCodeEnum.MINI_PROGRAM_SIGN_ERR.getErrorCode());
            }
            WelinkUserVO welinkUserVO = iWelinkServiceClient.login(code);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),welinkUserVO);
        }catch (Exception e){
            throw new DataAccessException("【WELINK sendBindPhoneMessageCode】发送验证码失败", e);
        }
    }

    /**
     * <desc>
     *      发送验证码
     * </desc>
     *
     * @param phoneNum
     *
     * @return MessageVO 标准格式化响应结果
     * @author Jiaqi.X
     * @createDate 2020/03/19
     */
    @PostMapping(path = "/user/sendBindPhoneMessageCode")
    @ResponseBody
    public Object sendBindPhoneMessageCode(String phoneNum,String createTime,String sign,HttpServletRequest request){
        try {
            phoneNum = request.getAttribute("phoneNum") == null ? null : request.getAttribute("phoneNum").toString();
            createTime = request.getAttribute("createTime") == null ? null : request.getAttribute("createTime").toString();
            sign = request.getAttribute("sign") == null ? null : request.getAttribute("sign").toString();
            if (StringUtils.isEmpty(phoneNum) || StringUtils.isEmpty(createTime)) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            //验签
            Map<String, String> params = new HashMap<>();
            params.put("createTime", createTime);
            params.put("phoneNum", phoneNum);
            //验证签名
            if (!Md5EncryptUtil.checkAppSignValue(params, sign, MINI_PROGRAM_REQUEST_PARAMS_ENCRYPT_KEY)) {
                return new MessageVO(MiniProgramErrorCodeEnum.MINI_PROGRAM_SIGN_ERR.getErrorCode());
            }
            //查询手机号是否被绑定
//            String welinkPhone = iWelinkServiceClient.checkBindPhone(phoneNum);
//            if (StringUtils.isNotBlank(welinkPhone)) {
//                phoneNum = welinkPhone;
//            }
            String smsCode = NumberHandlerUtil.randomNum(6);
            while (smsCode.substring(0,1).equals("0")){
                smsCode = NumberHandlerUtil.randomNum(6);
            }
            String content = "验证码:" + smsCode + ",该验证码将在30分钟后失效.";
            Map<String, Object> map = (HashMap) redisService.getObject(RedisConstant.WELINK_PHONE_SEND_MESSAGE_COUNT + phoneNum, HashMap.class);
            if (map == null) {
                map = new HashMap<>();
            }
            Integer count = (Integer) map.get("count");
            if (count == null) {
                count = 1;
            } else {
                count++;
            }
            if (count > 3) {
                return new MessageVO(MiniProgramErrorCodeEnum.BANK_CARD_SEND_MESSAGE_COUNT_SURPASS.getErrorCode());
            } else {
                map.put("count", count);
                map.put("smsCode", smsCode);
                iIotTpSmsServiceClient.sendSmsCodeByPhone(phoneNum, content);
                redisService.set(RedisConstant.WELINK_PHONE_SEND_MESSAGE_COUNT + phoneNum, RedisConstant.WELINK_PHONE_SEND_MESSAGE_COUNT_PHONE_SEND_MESSAGE_COUNT_TIME, map);
                //保存验证码
                boolean check = redisService.set(RedisConstant.WELINK_PHONE_SEND_MESSAGE_KEY + phoneNum,RedisConstant.WELINK_PHONE_SEND_MESSAGE_CACHE_TIME,smsCode);
                //LOG.info(String.format("【WELINK发送短信：手机号%s,%s】",phoneNum,check));
                return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode());
            }
        } catch (Exception e) {
            throw new DataAccessException("【WELINK sendBindPhoneMessageCode】发送验证码失败", e);
        }
    }

    /**
     * <desc>
     *      绑定手机
     * </desc>
     *
     * @param phoneNum
     *
     * @return MessageVO 标准格式化响应结果
     * @author Jiaqi.X
     * @createDate 2020/03/19
     */
    @PostMapping(path = "/user/bindPhone")
    @ResponseBody
    public Object bindPhone(String phoneNum,String welinkUserId,String messageCode,String type,String createTime,String sign,HttpServletRequest request) {
        try {
            phoneNum = request.getAttribute("phoneNum") == null ? null : request.getAttribute("phoneNum").toString();
            welinkUserId = request.getAttribute("welinkUserId") == null ? null : request.getAttribute("welinkUserId").toString();
            messageCode = request.getAttribute("messageCode") == null ? null : request.getAttribute("messageCode").toString();
            type = request.getAttribute("type") == null ? null : request.getAttribute("type").toString();
            createTime = request.getAttribute("createTime") == null ? null : request.getAttribute("createTime").toString();
            sign = request.getAttribute("sign") == null ? null : request.getAttribute("sign").toString();
            if (StringUtils.isEmpty(phoneNum) || StringUtils.isEmpty(createTime)) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            //验签
            Map<String, String> params = new HashMap<>();
            params.put("createTime", createTime);
            params.put("phoneNum", phoneNum);
            params.put("welinkUserId", welinkUserId);
            params.put("messageCode", messageCode);
            params.put("type",type);
            //验证签名
            if (!Md5EncryptUtil.checkAppSignValue(params, sign, MINI_PROGRAM_REQUEST_PARAMS_ENCRYPT_KEY)) {
                return new MessageVO(MiniProgramErrorCodeEnum.MINI_PROGRAM_SIGN_ERR.getErrorCode());
            }
            String smsCode;
            smsCode = (String) redisService.getObject(RedisConstant.WELINK_PHONE_SEND_MESSAGE_KEY + phoneNum, String.class);
            //LOG.info(String.format("【绑定手机获取验证码】：phoneNum %s  smscode%s",phoneNum,smsCode));
            if (StringUtils.isBlank(smsCode)) {
                return new MessageVO(PropertyErrorCodeEnum.BANK_CARD_SEND_MESSAGE_EXISTS.getErrorCode());
            }
            if (!smsCode.equals(messageCode)) {
                return new MessageVO(PropertyErrorCodeEnum.BANK_CARD_SEND_MESSAGE_ERROR.getErrorCode());
            } else {
                redisService.del(RedisConstant.WELINK_PHONE_SEND_MESSAGE_KEY + phoneNum);
                if(type.equals("3")){
                    return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode());
                }
            }
            WelinkBindRelationPO welinkBindRelationPO = new WelinkBindRelationPO();
            welinkBindRelationPO.setPhone(phoneNum);
            welinkBindRelationPO.setWelinkUserId(welinkUserId);
            welinkBindRelationPO.setType(Integer.valueOf(type));
            return new MessageVO(iWelinkServiceClient.save(welinkBindRelationPO), BaseErrorCodeEnum.SUCCESS.getErrorCode());
        }catch (Exception e){
            throw new DataAccessException("【WELINK bindPhone】绑定手机失败", e);
        }
    }
}